home *** CD-ROM | disk | FTP | other *** search
- From: "D. Allan Drummond" <allan.drummond@trilogy.com>
- Message-ID: <30FCDA77.69CB@trilogy.com>
- X-Original-Date: Wed, 17 Jan 1996 05:16:07 -0600
- Path: in2.uu.net!bounce-back
- Date: 18 Jan 96 02:05:47 GMT
- Approved: fjh@cs.mu.oz.au
- Newsgroups: comp.std.c++
- Subject: An STL helper -- and template and type shenanigans
- Organization: Trilogy
- X-Mailer: Mozilla 2.0b3 (WinNT; I)
- Cc: "std-c++@ncar.ucar.edu"@armadillo.trilogy.com
- X-Auth: PGPMoose V1.1 PGP comp.std.c++
- iQBFAgUBMP2rQuEDnX0m9pzZAQEAnwGAi32UgLsDQ1YCWkaJOzwu7n3FD9QJVWiz
- LP1F0BxD27xHyr5pKRzrRu1Hq9p9CP74
- =NuWH
-
- In writing an STL helper function, I ran into a snag. The helper function
- is used to make a deep copy of a list of pointers, so that the following
- code is possible:
-
- #include <list.h>
-
- class A {}
-
- main()
- {
- list<A*> alist;
- // Now add bunches of A*'s to the list...
-
- list<A*> other_alist;
- deep_copy( alist, other_alist );
-
- // Now modify contents of other_alist with impunity --
- // they're distinct from alist's.
- }
-
-
- Below are the two template functions that do the work.
-
- ----------------
-
- // deep_copy requires that class T have
- // a copy constructor, and for best use, one that
- // makes a deep copy.
-
- template<class Iter, class ContainedType>
- void deep_copy( Iter fromB, Iter fromE, Iter toB, Iter toE, ContainedType* )
- {
- while( (fromB != fromE) && (toB != toE) && *fromB )
- *toB++ = new T( **fromB++ );
- }
-
- template<class Container>
- void deep_copy( Container& from, Container& to )
- {
- to = from; // expand to make sure TO is as big as FROM.
- // should be cheap, if this is really a list of pointers.
- Container::value_type type;
- deep_copy( from.begin(), from.end(), to.begin(), to.end(), type );
- }
-
- -----------------
-
- Note: STL container classes all have a public typedef like this --
-
- typedef T value_type;
-
- The above set of functions will always be run on pointer-lists, where
- T is a pointer type.
-
- -----------------
-
-
- So, the obvious strange item is the ContainedType class in the top template
- header. The problem is that Container::value_type is a pointer type, so I
- can't say something like *toB = new Container::value_type( **fromB ) --
- that would make the rhs a **, which is not the desired *.
-
- The template mechanism has the strange ability to "dereference" types, so
- that when I pass a T* to the top function, I can then use the T type
- normally.
-
- This seems ugly to me. How can I get access to the type T (not T*) in the
- first function, so that I don't have to pass a bogus parameter to some
- second function?
-
-
- ( For the casual reader: You must use all template types in the function
- arguments. Consider a silly example:
-
- template<class T, class S> void foo( T t ) { S* s = new S; }
-
- How could the compiler figure out what S was from the following?
-
- A a;
- foo( a ); )
-
-
-
- I really want to write something like this (the following code is
- nonsensical but should convey the spirit of the idea):
-
- template<class Container>
- void deep_copy( Container& from, Container& to )
- {
- to = from; // expand to make sure TO is as big as FROM.
- // should be cheap, if this is really a list of pointers.
- Container::const_iterator f( from.begin() );
- Container::iterator t( to.begin );
-
- while( (f != from.end()) && (t != to.end()) && *f )
- *t++ = new (*Container::value_type)( **f++ );
- }
-
- It seems as though there's no REAL reason to have to split it into two
- functions, but the "type dereferencing" is crucial.
-
- Any suggestions? Incidentally, the two-function method works great --
- feel free to rip it off with impunity.
-
-
- Thanks,
-
- Allan
- allan.drummond@trilogy.com
- ---
- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
- Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
- is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
-